package ph.com.gs3.formalistics.service.managers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import ph.com.gs3.formalistics.R;
import ph.com.gs3.formalistics.global.utilities.logging.FLLogger;
import ph.com.gs3.formalistics.model.dao.UserAccountsDAO;
import ph.com.gs3.formalistics.model.valueobjects.business.User;
import ph.com.gs3.imagemanager.ImageLoader;
import android.content.Context;
import android.widget.ImageView;

/**
 * 
 * @author Ervinne Sodusta
 * 
 */
public class ImageManager {

	public static final String TAG = ImageManager.class.getSimpleName();

	public static final String IMAGE_CACHE_PATH = ".formalistics/img_cache";

	public ImageLoader imageLoader;

	private Map<String, List<ImageView>> queuedUserImageViews;
	private Map<String, String> downloadedImages;

	private int imageNotAvailableStub = R.drawable.user_avatar_empty;

	// TODO: check if this should be injected later
	private UserAccountsDAO userAccountsDAO;

	private static ImageManager defaultInstance;

	public static ImageManager getDefaultInstance(Context context) {

		if (defaultInstance == null) {
			defaultInstance = new ImageManager(context);
		}

		return defaultInstance;

	}

	public ImageManager(Context context) {

		imageLoader = new ImageLoader(context, IMAGE_CACHE_PATH);
		// imageLoader.setDefaultServer(server);
		imageLoader.setImageNotAvailableResource(imageNotAvailableStub);

		queuedUserImageViews = new HashMap<String, List<ImageView>>();
		downloadedImages = new HashMap<String, String>();

		userAccountsDAO = new UserAccountsDAO(context);

	}

	public void requestUserImage(String userWebId, String server, ImageView imageView) {

		if (userWebId == null || server == null) {
			FLLogger.d(TAG, "Requested user image but the user web id or server is not provided");
			return;
		}

		// get the user from the id provided
		userAccountsDAO.open();
		User user = userAccountsDAO.getUserWithWebIdAndServer(Integer.parseInt(userWebId), server);
		userAccountsDAO.close();

		if (user == null) {
			FLLogger.w(TAG, "User with id " + userWebId + " from server " + server
			        + " is not found. Display/download of image failed.");
			return;
		}

		String userDbId = Integer.toString(user.getId());

		// check if the image has be fetched already.
		if (downloadedImages.containsKey(userDbId)) {
			// the image is existing, simply load the image to the image view
			imageLoader.displayImage(downloadedImages.get(userDbId), imageView);
		} else {

			imageView.setImageResource(imageLoader.getImageNotAvailableResource());

			if (queuedUserImageViews.containsKey(userDbId)) {
				// register the image view to an existing list
				queuedUserImageViews.get(userDbId).add(imageView);
			} else {
				// create a new list for this user and request for the user's data
				List<ImageView> userImageViewQueue = new ArrayList<ImageView>();
				userImageViewQueue.add(imageView);
				queuedUserImageViews.put(userDbId, userImageViewQueue);

				// TODO: check if there is a need for re checking connection here

				downloadImage(user);

			}
		}

	}

	public void downloadImage(User user) {

		String userId = Integer.toString(user.getId());

		if (!queuedUserImageViews.containsKey(userId)) {
			// The image view list was suddenly lost, this may be caused
			// by changing activities etc., ignore and abort operation
			return;
		}

		// load the image to each image views of the corresponding users
		List<ImageView> userImageViews = queuedUserImageViews.get(userId);

		if (user != null && user.getImageURL() != null && !user.getImageURL().isEmpty()
		        && !"null".equals(user.getImageURL().toLowerCase(Locale.ENGLISH))) {

			for (ImageView currentUserImageView : userImageViews) {
				imageLoader.displayImage(user.getImageURL(), currentUserImageView);
			}

			// get the full image url from the user's account server and image url
			String server = user.getAccountServer();
			String imageURL = user.getImageURL();
			String fullImageURL = getFullURL(server, imageURL);

			// images that are already downloaded should have their
			// corresponding image views removed from the queue, a reference
			// to the image will now be stored in the "downloadedImages" map
			// and will be used by other image views instead of downloading
			// the image again.
			queuedUserImageViews.remove(user.getId());
			downloadedImages.put(userId, fullImageURL);

		} else {
			for (ImageView currentUserImageView : userImageViews) {
				currentUserImageView.setImageResource(imageLoader.getImageNotAvailableResource());
			}
		}

	}

	private String getFullURL(String server, String url) {

		if (url.indexOf("/") == 0) {
			url = server + url;
		} else {
			url = server + "/" + url;
		}

		return url;

	}

}
